﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ReprojectWebMercator
{
    public class vec4
    {
        public float x, y, z, w;

        #region 属性
        public vec3 rgb
        {
            get { return new vec3(x, y, z); }
            set
            {
                x = value.x;
                y = value.y;
                z = value.z;
            }
        }
        public float a
        {
            get { return w; }
            set
            {
                w = value;
            }
        }
        public float r
        {
            get { return x; }
            set
            {
                x = value;
            }
        }
        public float g
        {
            get { return y; }
            set
            {
                y = value;
            }
        }
        public float b
        {
            get { return z; }
            set
            {
                z = value;
            }
        }
        #endregion

        #region 部分值

        public override string ToString()
        {
            return x.ToString("f3") + "  " + y.ToString("f3") + " " + z.ToString("f3") + " " + w.ToString("f3");
        }
        
        public vec2 xy
        {
            get { return new vec2(x, y); }
            set
            {
                x = value.x;
                y = value.y;
            }
        }
        public vec2 xx
        {
            get { return new vec2(x, x); }
        }
        public vec2 yy
        {
            get { return new vec2(y, y); }
        }
        public vec2 zw
        {
            get { return new vec2(z, w); }
        }
        public vec2 xz
        {
            get { return new vec2(x, z); }
        }
        public vec2 yw
        {
            get { return new vec2(y, w); }
        }
        

        public vec3 xyz
        {
            get { return new vec3(x, y, z); }
            set
            {
                x = value.x;
                y = value.y;
                z = value.z;
            }
        }
        public vec3 www
        {
            get { return new vec3(w, w, w); }
        }
        public vec4 xxzz
        {
            get { return new vec4(x, x, z, z); }
        }
        public vec2 get2(string v)
        {
            return new vec2(getT(v[0]), getT(v[1]));
        }
        public vec3 get3(string v)
        {
            return new vec3(getT(v[0]), getT(v[1]), getT(v[2]));
        }
        public vec4 get4(string v)
        {
            return new vec4(getT(v[0]), getT(v[1]), getT(v[2]), getT(v[3]));
        }
        private float getT(char t)
        {
            if (t == 'x') return x;
            if (t == 'y') return y;
            if (t == 'z') return z;
            if (t == 'w') return w;
            return 0;
        }
        #endregion

        public vec4(vec2 u_textureDimensions, float v1, float v2)
        {
            this.x = u_textureDimensions.x;
            this.y = u_textureDimensions.y;
            this.z = v1;
            this.w = v2;
        }

        public vec4(float v1, float v2, float v3, float v4)
        {
            this.x = v1;
            this.y = v2;
            this.z = v3;
            this.w = v4;
        }
        public vec4(double v1, double v2, double v3, double v4)
        {
            this.x = (float)v1;
            this.y = (float)v2;
            this.z = (float)v3;
            this.w = (float)v4;
        }

        public vec4 Dot(vec4 other)
        {
            return new vec4(x * other.x, y * other.y, z * other.z, w * other.w);
        }

        public double length()
        {
            return Math.Sqrt(x*x+y*y+z*z+w*w);
        }

        public static vec4 operator -(vec4 v1, vec4 v2)
        {
            return new vec4(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.w - v2.w);
        }
        public static vec4 operator +(vec4 v1, vec4 v2)
        {
            return new vec4(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.w + v2.w);
        }
        public static vec4 operator +(double v1, vec4 v2)
        {
            return new vec4(v1 + v2.x, v1 + v2.y, v1 + v2.z, v1 + v2.w);
        }
        public static vec4 operator -(vec4 v1, double v2)
        {
            return new vec4(v1.x - v2, v1.y - v2, v1.z - v2, v1.w - v2);
        }
        public static vec4 operator -(double v1, vec4 v2)
        {
            return new vec4(v1 - v2.x, v1 - v2.y, v1 - v2.z, v1 - v2.w);
        }
        public static vec4 operator +(vec4 v1, double v2)
        {
            return new vec4(v1.x + v2, v1.y + v2, v1.z + v2, v1.w + v2);
        }
        public static vec4 operator *(vec4 v1,double t)
        {
            return new vec4(v1.x * t, v1.y * t, v1.z * t, v1.w * t);
        }
        public static vec4 operator *(double v1, vec4 t)
        {
            return new vec4(v1 * t.x, v1 * t.y, v1 * t.z, v1 * t.w);
        }
        public static vec4 operator *(vec4 v1, float t)
        {
            return new vec4(v1.x*t, v1.y * t, v1.z * t, v1.w * t);
        }
        public static vec4 operator *(vec4 v1, vec4 t)
        {
            return new vec4(v1.x * t.x, v1.y * t.y, v1.z * t.z, v1.w * t.w);
        }
        public static vec4 operator /(vec4 v1, float t)
        {
            return new vec4(v1.x / t, v1.y / t, v1.z / t, v1.w / t);
        }
        public static vec4 operator /(vec4 v1, vec4 t)
        {
            return new vec4(v1.x / t.x, v1.y / t.y, v1.z / t.z, v1.w / t.w);
        }
    }
}
